Swift Chartsを使って線グラフを表示する
新しく開発中の個人アプリでチャートを表示させたいと考え、過去に何度も使用しており、カスタマイズのノウハウもある「DGCharts (旧:iOS Charts)」の利用を検討したが、せっかくなのでiOS 16以降で利用可能な「Swift Charts」を試してみることにした。
検証環境
- MacBook Pro (16-inch, 2023)
- Apple M2 Pro
- Xcode 15.2
- macOS 14.3.1
Swift Chartsを使って線グラフを表示する
Swift Chartsの利用方法は非常に簡単で、Chart Viewを使って実装する。Charts
フレームワークをimportする必要がある。
import Charts
次に、Viewのbody内で以下のように実装する。株価を想定しており、x軸にdate、y軸にpriceを設定している。
struct ContentView: View { var body: some View { VStack { Chart { LineMark( x: .value("date", "2024/3/21"), y: .value("price", 26.99) ) LineMark( x: .value("date", "2024/3/22"), y: .value("price", 27.57) ) LineMark( x: .value("date", "2024/3/26"), y: .value("price", 27.20) ) } .frame(height: 200) } .padding() } }
実行すると下図のように表示される。
Y軸の表示範囲を指定する
この例では、priceの範囲が26.99〜27.20である。0.0〜20.0 にデータは存在せず、ユーザーにとっても見る必要のない範囲である。表示範囲を狭めたい場合、chartYScale
modifier が利用できる。
struct ContentView: View { var body: some View { VStack { Chart { // ... } .chartYScale(domain: 20...35) .frame(height: 200) } .padding() } }
実行すると下図のように表示される。
Y軸にラベルを追加する
Y軸には、priceの26.99〜27.20の値が表示されるが、初見では単位がよくわからないだろう。Y軸の単位がUSDであることを明示したい。これにはchartYAxisLabel
modifierを使用する。
struct ContentView: View { var body: some View { VStack { Chart { // ... } .chartYAxisLabel(position: .trailing, alignment: .center, spacing: 10) { Text("USD") .font(.system(size: 15, weight: .bold)) } .frame(height: 200) } .padding() } }
実行すると下図のように表示される。
より実践的にデータを扱う場合
通常、グラフは固定値を表示させるものではない。ViewModelなどを通じてデータベースから取得したデータをグラフに表示できるように整形する必要がある。そこで、日付と価格を格納するPortfolioChartData
structを定義した。
struct PortfolioChartData: Identifiable { let id = UUID() let x: Date let y: Decimal }
次にPortfolioChartData
の配列をパラメータにして、線グラフを表示させる PortfolioChartView
を追加した。
struct PortfolioChartView: View { let items: [PortfolioChartData] var body: some View { Chart(items) { item in LineMark( x: .value("date", item.x), y: .value("price", item.y) ) } .chartYScale(domain: 40...120) .chartYAxisLabel(position: .trailing, alignment: .center, spacing: 10) { Text("USD") .font(.system(size: 15, weight: .bold)) } .chartXAxis { AxisMarks(values: .automatic) } } }
親ViewのContentViewでは以下のように実装している。この例では、グラフに表示するデータをViewのコンストラクタで生成しているが、あまりよくない例なので割り切って欲しい。
struct ContentView: View { let items: [PortfolioChartData] init() { items = ContentView.getData() } var body: some View { VStack { PortfolioChartView(items: items) .frame(height: 200) } .padding() } private static func getData() -> [PortfolioChartData] { // 表示用のランダムなデータを生成する let now = Date.now let calendar = Calendar.current var items: [PortfolioChartData] = [] (0 ... 14).forEach { index in let date = calendar.date(byAdding: .day, value: index - 14, to: now)! let item = PortfolioChartData( x: date, y: Decimal(Int.random(in: 50 ... 110)) ) items.append(item) } return items } }
実行すると下図のように表示される。
まとめ
Swift Chartsを十分に使いこなせているわけではないが、DGChartsと比べると機能面で劣っている印象がある。
iOS 15をサポートしなければならない場合、Swift Chartsは選択肢にはならない。しかし、iOS 16以降をサポートするアプリであれば、簡単にチャートが実装できるSwift Chartsと、より詳細なカスタマイズが可能だが使いにくいDGChartsのどちらを使用するかについては、アプリの要件に応じて決めることもひとつの手だ。
直近では、Privacy Manifest対応などAppleからサードパーティSDKに求められることが増えており、SDKの利用者も対応に追われることが多い。Swift ChartsはDGChartsに比べて機能面でシンプルに設計されており、DGChartsのような高度なカスタマイズオプションを求める場合は物足りないかもしれないが、Appleの公式フレームワークであるため、将来のOSアップデートにおいても安定した動作が期待できる。
強い要望がない場合や、アプリの要件が許すのであれば、今後はSwift Chartsを使用する方が良いかもしれない。